home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / transblt / tblt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-21  |  6.7 KB  |  274 lines

  1. #include <windows.h>
  2. #include <mmsystem.h>
  3. #include "tblt.h"
  4.  
  5. #define  DSNA  0x00220326L    // the magical ROP
  6.  
  7. BOOL FAR PASCAL doTransBlit(HDC hDC, int x, int y, int dx, int dy, 
  8.     HBITMAP hBitmap0, BITMAP FAR * lpBitmap, int x0, int y0,
  9.     HBITMAP FAR * lphBitmapMask, COLORREF transColor, DWORD dwFlags)
  10. {
  11. static bTrans=-23;    // magic value for init compare
  12.     RECT    rc;
  13.  
  14.     HDC        hImageDC=NULL;
  15.     HDC        hMaskDC=NULL;
  16.     HDC         tempDC=NULL;
  17.     
  18.     HANDLE      hOldObj=NULL;
  19.     
  20.     HBITMAP    hBitmapMask=NULL;
  21.     HBITMAP    hOBitmapMask=NULL;
  22.     HBITMAP    hOBitmapImage=NULL;
  23.     HBITMAP     tempBit=NULL;
  24.     BOOL    fMask;
  25.     BOOL    fScreen;
  26.     WORD    xOff, yOff;
  27.  
  28.     if(!hDC || !hBitmap0)
  29.     return FALSE;
  30.     
  31.     if(bTrans==-23 || dwFlags & TRANS_FORCECALCCAPS)
  32.     bTrans = GetDeviceCaps(hDC, CAPS1) & C1_TRANSPARENT;
  33.  
  34.     fMask=(dwFlags&TRANS_SAVEMASK)!=0;
  35.     fScreen=(dwFlags&TRANS_FORCESCREEN)!=0;
  36.  
  37.     if(!dx) // if none provided, assume full bitmap
  38.     dx=lpBitmap->bmWidth;
  39.     if(!dy) // if none provided, assume full bitmap
  40.     dy=lpBitmap->bmHeight;
  41.  
  42.     if((x0+dx) >lpBitmap->bmWidth)
  43.     return FALSE;
  44.     
  45.     if((y0+dy) >lpBitmap->bmHeight)
  46.     return FALSE;
  47.     
  48.     if ( (lpBitmap->bmPlanes==1) && (lpBitmap->bmBitsPixel==1) )
  49.     {
  50.     // If mono source, do it in one ROP....
  51.         
  52.     hImageDC   = CreateCompatibleDC(hDC);
  53.     if(!hImageDC)
  54.         goto error;
  55.     
  56.     hOBitmapImage=SelectObject(hImageDC, hBitmap0);
  57.  
  58.         BitBlt(hDC, x, y, dx, dy, hImageDC, x0, y0, SRCPAINT);
  59.     
  60.     SelectObject(hImageDC,hOBitmapImage);
  61.     DeleteDC(hImageDC);
  62.     
  63.         return TRUE;
  64.     }
  65.     
  66.     if(bTrans && !(dwFlags & TRANS_FORCEOLD))
  67.     {
  68.     // if it is available and they don't tell us not to use it...
  69.  
  70.     if(!(dwFlags & TRANS_NOSAVEDC))
  71.         SaveDC(hDC);
  72.     
  73.     SetBkColor(hDC, transColor);
  74.     SetBkMode(hDC, NEWTRANSPARENT);
  75.  
  76.     // Get source image...
  77.     hImageDC   = CreateCompatibleDC(hDC);
  78.     if(!hImageDC)
  79.         goto error;
  80.     
  81.     hOBitmapImage=SelectObject(hImageDC, hBitmap0);
  82.         
  83.  
  84.     BitBlt (hDC, x, y, dx, dy, hImageDC,
  85.               x0, y0,SRCCOPY);
  86.           
  87.     SelectObject(hImageDC, hOBitmapImage);
  88.     DeleteDC(hImageDC);
  89.         
  90.     if(!(dwFlags & TRANS_NOSAVEDC))
  91.         RestoreDC(hDC,-1);
  92.     return TRUE;
  93.     }
  94.     else
  95.     {
  96.     
  97.     if(!(dwFlags & TRANS_NOSAVEDC))
  98.         SaveDC(hDC);
  99.  
  100.     hImageDC   = CreateCompatibleDC(hDC);
  101.     hMaskDC    = CreateCompatibleDC(hDC);
  102.     if(!hImageDC || !hMaskDC)
  103.         goto error;
  104.  
  105.     hOBitmapImage=SelectObject(hImageDC, hBitmap0);
  106.  
  107.     // We can optimize speed more by saving mask bitmap instead of
  108.     // re-creating it every time, but this takes up more memory
  109.  
  110.     // this only helps if the driver does not support transparent blits
  111.     // directly.
  112.  
  113.     if(lphBitmapMask)
  114.         hBitmapMask=*lphBitmapMask;
  115.     else
  116.         hBitmapMask=0;
  117.     
  118.     if(!fMask && hBitmapMask)
  119.     {
  120.         // an old one was floating around...
  121.         DeleteObject(hBitmapMask);
  122.         hBitmapMask=NULL;
  123.         *lphBitmapMask=NULL;
  124.     }
  125.         
  126.     if(!hBitmapMask)
  127.     {
  128.         // note: we create mask for entire bitmap, even if we
  129.         // only want to use part of it.   This makes sense
  130.         // if we are using 'tiled' bitmaps (see GRAPHX technote)
  131.         // and we are saving the mask bitmap.
  132.         
  133.         hBitmapMask = CreateBitmap(lpBitmap->bmWidth, lpBitmap->bmHeight, 1, 1, NULL);
  134.         hOBitmapMask=SelectObject(hMaskDC, hBitmapMask);
  135.         
  136.         // set background color for color-to-mono conversion
  137.         // (bk color will be white(1), all else is black (0) )
  138.         SetBkColor(hImageDC, transColor);
  139.         
  140.         BitBlt(hMaskDC,  0, 0, lpBitmap->bmWidth, lpBitmap->bmHeight,
  141.             hImageDC, 0, 0, SRCCOPY);
  142.            
  143.         // invert 1s and 0s to get valid mask..(could also use
  144.         // bitblt() and DSTINVERT ROP
  145.         rc.left=rc.top=0;
  146.         rc.right=lpBitmap->bmWidth;
  147.         rc.bottom=lpBitmap->bmHeight;
  148.         InvertRect(hMaskDC,&rc);
  149.         
  150. #ifdef MASKDEBUG
  151.         BitBlt(hDC, 0, 0, lpBitmap->bmWidth, lpBitmap->bmHeight,
  152.             hMaskDC, 0, 0, SRCCOPY);
  153. #endif
  154.     }
  155.     else
  156.     {
  157.         // re-use mask bitmap from last time.
  158.             
  159.         hOBitmapMask=SelectObject(hMaskDC, hBitmapMask);
  160.         
  161. #ifdef MASKDEBUG
  162.         BitBlt(hDC, 0, 0, lpBitmap->bmWidth, lpBitmap->bmHeight,
  163.             hMaskDC, 0, 0, SRCCOPY);
  164. #endif
  165.     }
  166.     // now we have mask bitmap: we can continue
  167.         
  168.     if(!fScreen)
  169.     {
  170.         // Do work off-screen so we don't see flash of INVERTS
  171.         // This is a little slower (but if you're keeping an off-screen
  172.         // bitmap of the screen anyway you should use it)
  173.         
  174.         tempDC = CreateCompatibleDC (hDC);
  175.         tempBit = CreateCompatibleBitmap(hDC, dx, dy);
  176.         hOldObj = SelectObject (tempDC, tempBit);
  177.  
  178.         // copy what's on the screen first
  179.         BitBlt (tempDC, 0, 0, dx, dy, hDC, x, y, SRCCOPY);
  180.         xOff=0;
  181.         yOff=0;
  182.     }
  183.     else
  184.     {
  185.         // for 'old' way:
  186.         // MAYBE faster, definitely saves memory, but very much uglier.
  187.         // it might not be faster because system-memory operations
  188.         // are usually faster than screen-memory operations
  189.         // (see the Graphics Design Technote)
  190.         // saves memory 'cause no temp DC and bitmap
  191.         // uglier 'cause operations are visible and flash
  192.  
  193.         // for 'new' way: (if supported)
  194.         // faster, not ugly, some memory savings
  195.         // faster 'cause no extra time for copying temp bitmap
  196.         // saves memory 'cause no temp DC and bitmap
  197.             
  198.         tempDC=hDC;    // do work directly on target DC (screen)
  199.         xOff=x;
  200.         yOff=y;
  201.     }
  202.     
  203.     // these three blits do the work...
  204.         
  205.     BitBlt(tempDC,   xOff, yOff, dx, dy,
  206.            hImageDC, x0, y0, SRCINVERT);
  207.  
  208.     BitBlt(tempDC,   xOff, yOff, dx, dy,
  209.            hMaskDC,  x0, y0, DSNA);
  210.  
  211.     BitBlt(tempDC,   xOff, yOff, dx, dy,
  212.            hImageDC, x0, y0, SRCINVERT);
  213.  
  214.     if(!fScreen)
  215.     {
  216.         // put it all on the target device
  217.             
  218.         BitBlt (hDC, x, y, dx, dy, tempDC,
  219.             0, 0,SRCCOPY);
  220.             
  221.         // clean up off-screen bitmaps
  222.         SelectObject(tempDC, hOldObj);
  223.         DeleteDC(tempDC);
  224.         DeleteObject(tempBit);
  225.         
  226.     } // else it is already there...
  227.     
  228.     SelectObject(hMaskDC, hOBitmapMask);
  229.     DeleteDC(hMaskDC);
  230.     
  231.     SelectObject(hImageDC, hOBitmapImage);
  232.     DeleteDC(hImageDC);
  233.     
  234.     if(!fMask)
  235.     {
  236.         DeleteObject(hBitmapMask);
  237.         hBitmapMask=NULL;
  238.     }
  239.     else if(lphBitmapMask)
  240.         *lphBitmapMask=hBitmapMask;
  241.     
  242.     if(!(dwFlags & TRANS_NOSAVEDC))
  243.         RestoreDC(hDC,-1);
  244.     return TRUE;
  245.     }
  246. error:
  247.     if(tempDC)
  248.     {
  249.     if(hOldObj)
  250.         SelectObject(tempDC, hOldObj);
  251.     DeleteDC(tempDC);
  252.     }
  253.     if(hMaskDC)
  254.     {
  255.     if(hOBitmapMask)
  256.         SelectObject(hMaskDC, hOBitmapMask);
  257.     DeleteDC(hMaskDC);
  258.     }
  259.     if(hImageDC)
  260.     {
  261.     if(hOBitmapImage)
  262.         SelectObject(hImageDC, hOBitmapImage);
  263.     DeleteDC(hImageDC);
  264.     }
  265.     if(tempBit)
  266.     DeleteObject(tempBit);
  267.     if(hBitmapMask)
  268.     DeleteObject(hBitmapMask);
  269.     if(lphBitmapMask)
  270.     *lphBitmapMask=0;
  271.     return FALSE;
  272.     
  273. }
  274.